'''
使用手写检测服务来做空白作答分类
'''

import requests
import json
from utils.http_utils import *
from utils.cv2_utils import get_file_content_as_base64, detect_handwritten_text, imread_unicode_path, get_image_from_url, pillow_to_cv2
import time

class BlankAnswerClassifier:
    '''
    空白作答检测分类
    '''
    def __init__(self):
        """
        初始化函数
        :param service_url: 手写检测服务的URL
        """
        #self.service_url = "http://yj-hw-ocr.haofenshu.com/get_hw_ocr_result"
        self.service_url = "http://yj-hw-ocr.haofenshu.com/blank_answer_classify"
        # self.service_url = "https://fx-business.haofenshu.com/blank_answer_classify"

    def classify(self, image_path=None, image_url=None):
        """
        公开的分类接口，用于调用手写检测服务并返回分类结果
        :param image_path: 图像文件的路径
        :return: 判断结果，字符串形式
        """
        try:
            is_blank_answer = False
            start_time = time.time()
            # # 先用传统的方法试一遍，找出那些不确定的图再跑检测模型
            # has_handwritten_text = self._detect_handwritten_text_by_contours_feature(image_path=image_path, image_url=image_url)
            # # 如果比较确定包含手写的内容，则直接返回
            # if has_handwritten_text:
            #     return is_blank_answer
            # 调用私有接口进行手写检测服务调用
            response = self._call_handwriting_service(image_path=image_path, image_url=image_url)
            # 调用私有接口解析响应数据
            handwritten_data = self._parse_response_data(response)
            # 调用私有接口判断是否是空白作答
            is_blank_answer = self._determine_if_blank_answer(handwritten_data)
            end_time = time.time()
            elapsed_time = end_time - start_time
            print(f"[INFO] 执行时间: {elapsed_time:.4f} 秒")
            return is_blank_answer
        except Exception as e:
            print(f"Error during classification: {e}")
            return False

    def _call_handwriting_service(self, image_path=None, image_url=None):
        """
        私有接口，调用手写检测服务
        :param image_path: 图像文件的路径
        :return: 服务的响应
        """
        try:
            post_data = None 
            response = None
            subject = '语文'
            # 本地
            if image_path is not None:
                post_data = json.dumps(
                    {"im_base64": get_file_content_as_base64(image_path), "subject": subject, 'from_src': "blank_answer"})  # post图片的base64编码
            elif image_url is not None:
                post_data = json.dumps({"im_url": image_url, "subject": subject, 'from_src': "blank_answer"})  # post图片的url地址

            if post_data is not None:
                response = post_request(self.service_url, data=post_data)
                #print('response status: ', response.status_code)
                #print('response text: ', response.text)

            return response
        except requests.RequestException as e:
            print(f"Error calling handwriting service: {e}")
            raise

    def _parse_response_data(self, response):
        """
        私有接口，解析手写检测服务的响应数据
        :param response: 手写检测服务的响应
        :return: 解析后的数据
        """
        try:
            if response is None or response.status_code != 200:
                return None
            response_data = response.json()
            #print('response data: ', response_data)
            #print('type : ', type(response_data))
            code = response_data.get("code")
            # 正常code会返回0
            if code != 0:
                return None
            handwritten_data = response_data.get('data')
            if handwritten_data is not None:
                handwritten_data = json.loads(handwritten_data)
            return handwritten_data
        except ValueError as e:
            print(f"Error parsing response data: {e}")
            raise

    def _determine_if_blank_answer(self, handwritten_data):
        """
        私有接口，基于解析的内容进行判断是否是空白作答
        :param handwriting: 手写内容
        :return: 判断结果，布尔值
        """
        
        if handwritten_data is not None:
            boxes_coord = handwritten_data.get("boxes_coord")
            #labellist = response_data.get("labellist")
            
            # 假设如果解析内容为空或仅包含空白字符，则认为是空白作答
            if len(boxes_coord) <= 0:
                #print("Blank Answer") 
                return True
            else:
                #print("Not Blank Answer") 
                return False
        else:
            return False
        
    def _get_image(self, image_path=None, image_url=None):
        """
        私有接口，获取图像内容
        :param image_path: 图像文件的路径
        :return: 图像内容
        """
        if image_path is not None:
            return imread_unicode_path(image_path)
        elif image_url is not None:
            pillow_img = get_image_from_url(image_url)
            cv2_img = pillow_to_cv2(pillow_img)
            return cv2_img
        else:
            return None
        
    def _detect_handwritten_text_by_contours_feature(self, image_path=None, image_url=None):
        """
        私有接口，通过轮廓特征进行手写文本检测
        :return: 检测结果，布尔值
        """
        start_time = time.time()

        image = self._get_image(image_path=image_path, image_url=image_url)

        elapsed_time = time.time() - start_time
        print(f"[INFO] get_image 执行时间: {elapsed_time:.4f} 秒")

        start_time = time.time()
        feature_position = detect_handwritten_text(image)
        elapsed_time = time.time() - start_time
        print(f"[INFO] detect_handwritten_text 执行时间: {elapsed_time:.4f} 秒")
        
        # 使用传统的图像处理方法找特征点，如果找到的点比较少则可能是没有手写内容的，需要使用手写检测模型再检测一轮
        # 否则认为是有手写内容的
        if feature_position is not None or len(feature_position) < 5:
            #print("No Handwritten Text Detected")
            return False
        else:
            #print("Handwritten Text Detected")
            return True
        


# 使用示例
if __name__ == "__main__":
    #service_url = "http://yj-hw-ocr.haofenshu.com/get_hw_ocr_result"
    service_url = "http://192.168.1.16:9999/blank_answer_classify"
    output_path = './outputs'
    classifier = BlankAnswerClassifier()
    image_path = "D:\\work\\code\\fx-business\\data\\blank_answer\\2463850F-40C7-11EF-82B9-6C4B908ECC86.png"
    classification_result = classifier.classify(image_path=image_path)
    print(classification_result)


